package com.example;

import io.quarkus.hibernate.reactive.panache.Panache;
import io.quarkus.hibernate.reactive.panache.PanacheEntityBase;
import io.quarkus.hibernate.reactive.panache.PanacheQuery;
import io.quarkus.hibernate.reactive.panache.common.runtime.ReactiveTransactional;
import io.quarkus.panache.common.Page;
import io.smallrye.mutiny.Uni;

import java.util.List;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

/**
 * reactive反应式分页目前推荐：分页集合和分页页码数据分开两个接口，目前测试的结果聚合在一个接口都会报错
 * 
 * @author weir
 *
 */
@Path("/client")
public class CountriesResource {

	@Inject
	PageService pageService;

	@GET
	@Path("/{id}")
	public Uni<Comments> get(@PathParam("id") Integer id) {
		return Comments.findById(id);
	}

	@GET
	@Path("get2/{id}")
	public Uni<Integer> get2(@PathParam("id") Integer id) {

		return Uni.createFrom().item(22);
	}

	// 报错，(Session/EntityManager is closed)
	@GET
	@Path("list-page/{pageIndex}/{pageSize}")
	public Uni<PageListDTO<Comments>> listPage(@PathParam("pageIndex") Integer pageIndex,
			@PathParam("pageSize") Integer pageSize) {
		PanacheQuery<Comments> page = Comments.findAll().page(pageIndex, pageSize);

		return Uni.combine().all().unis(page.list(), page.count()).combinedWith((list, num) -> {
			PageListDTO<Comments> qr = new PageListDTO<>();
			qr.list = list;
			qr.count = num;
			return qr;
		});
	}
	/**
	 * 分页问题解决
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	@GET
	@Path("list-page2/{pageIndex}/{pageSize}")
	public Uni<PageListDTO<Comments>> listPage2(@PathParam("pageIndex") Integer pageIndex,
			@PathParam("pageSize") Integer pageSize) {
		
		return Panache.withTransaction(() -> {
			PanacheQuery<Comments> findAll = Comments.findAll();
			Uni<Long> count = findAll.count();
			Uni<List<Comments>> list = findAll.page(Page.of(pageIndex, pageSize)).list();
			return Uni.combine().all().unis(count, list).combinedWith((c, l) -> new PageListDTO<Comments>(c, l));
		});
	}

//  报错
	@GET
	@Path("list-page-session/{pageIndex}/{pageSize}")
	public Uni<PageListDTO<Comments>> listPageForSession(@PathParam("pageIndex") Integer pageIndex,
			@PathParam("pageSize") Integer pageSize) {
		Uni<List<Comments>> page = Comments.findAll().page(pageIndex, pageSize).list();
//    	page.await().indefinitely();
		Uni<Object> pageCount = pageService.pageCount();
//    	pageCount.await().indefinitely();
		return Uni.combine().all().unis(page, pageCount).combinedWith((list, num) -> {
			PageListDTO<Comments> qr = new PageListDTO<>();
			qr.list = list;
			qr.count = Long.valueOf(num.toString());
			return qr;
		});
	}

//  报错
	@GET
	@Path("list-page-all-session/{pageIndex}/{pageSize}")
	public Uni<PageListDTO<Comments>> listPageALLSession(@PathParam("pageIndex") Integer pageIndex,
			@PathParam("pageSize") Integer pageSize) {
		Uni<List<Comments>> pageList = pageService.pageList(pageIndex, pageSize);
		pageList.await().indefinitely();
		Uni<Object> pageCount = pageService.pageCount();
		pageCount.await().indefinitely();
		return Uni.combine().all().unis(pageList, pageCount).combinedWith((list, num) -> {
			PageListDTO<Comments> qr = new PageListDTO<>();
			qr.list = list;
			qr.count = Long.valueOf(num.toString());
			return qr;
		});
	}

	@GET
	@Path("list/{pageIndex}/{pageSize}")
	public Uni<List<PanacheEntityBase>> list(@PathParam("pageIndex") Integer pageIndex,
			@PathParam("pageSize") Integer pageSize) {
		return Comments.findAll().page(pageIndex, pageSize).list();
	}

	@GET
	@Path("list-session/{pageIndex}/{pageSize}")
	public Uni<List<Comments>> listForSession(@PathParam("pageIndex") Integer pageIndex,
			@PathParam("pageSize") Integer pageSize) {
		return pageService.pageList(pageIndex, pageSize);
	}

	@ReactiveTransactional
	@GET
	@Path("list-page/{pageIndex}/{pageSize}")
	public Uni<PageListDTO> listForPage(@PathParam("pageIndex") Integer pageIndex,
			@PathParam("pageSize") Integer pageSize) {
		var page = Comments.findAll().page(pageIndex, pageSize);
		var chain = page.list().chain(list -> {
			PageListDTO pageListDTO = new PageListDTO();
			pageListDTO.list = list;
			return Uni.createFrom().item(pageListDTO);
		});
		return chain.chain(pageListDTO -> page.count().chain(count -> {
			pageListDTO.count = count;
			return Uni.createFrom().item(pageListDTO);
		}));
	}

	@GET
	@Path("list/count")
	public Uni<Long> listCount() {
		return Comments.count();
	}

	@GET
	@Path("list-session/count")
	public Uni<Object> listCountForSession() {
		return pageService.pageCount();
	}
}